package pt.inescid.components.policyengine.heimdall.pap.base;

import java.util.Vector;

import pt.inescid.components.policyengine.heimdall.base.EventObj;
import pt.inescid.components.policyengine.heimdall.base.User;

public abstract class RuleDefinition {

//  ----------------------------------------------------------
//  ------------------------   constants   ------------------------
//  ----------------------------------------------------------
	public static final String[] RULE_TYPE_CODES = {
		"and",
		"or",
		"not",
		"equals",
		"greaterThan",
		"lesserThan",

		"add",
		"subtract",
		"multiply",
		"divide",

		"literal",
		"subPolicy",
		"eventField",
		"cesSum",
		"externalMethod"
	};
	
	public static final int LOGICAL_AND_OPERATOR = 0;
	public static final int LOGICAL_OR_OPERATOR = 1;
	public static final int LOGICAL_NOT_OPERATOR = 2;
	public static final int EQUALS_OPERATOR = 3;
	public static final int GREATER_THAN_OPERATOR = 4;
	public static final int LESSER_THAN_OPERATOR = 5;

	public static final int ADD_OPERATOR = 6;
	public static final int SUBTRACT_OPERATOR = 7;
	public static final int MULTIPLY_OPERATOR = 8;
	public static final int DIVIDE_OPERATOR = 9;

	public static final int LITERAL_EXPRESSION = 10;
	public static final int SUBPOLICY_EXPRESSION = 11;
	public static final int EVENT_FIELD_EXPRESSION = 12;
	public static final int CES_SUM_EXPRESSION = 13;
	public static final int EXTERNAL_METHOD_EXPRESSION = 14;

	
	public static final String[] EXPRESSION_VALUE_CODES = {
		"string",
		"int",
		"boolean",
		"long",
		"timestamp"
		};

	public static final String[] SQL_EXPRESSION_VALUE_CODES = {
		"VARCHAR(255)",
		"INT(11)",
		"BOOLEAN",
		"INT(11)",
		"DATETIME"
		};

public static final int STRING_VALUE = 0;
	public static final int INT_VALUE = 1;
	public static final int BOOLEAN_VALUE = 2;
	public static final int LONG_VALUE = 3;
	public static final int TIMESTAMP_VALUE = 4;


	
	//  ----------------------------------------------------------
//  ------------------------   STATIC variables   ------------------------
//  ----------------------------------------------------------
	protected static int ruleCounter = 0;
	
//  ----------------------------------------------------------
//  ------------------------   INSTANCE variables   ------------------------
//  ----------------------------------------------------------
	protected int id;
	protected int type;
	protected int valueType;
	protected RuleDefinition previousLevel;

	//  ----------------------------------------------------------
//  ------------------------   constructors   ------------------------
//  ----------------------------------------------------------
	public RuleDefinition(int type,	RuleDefinition previousLevel) {
		this.id = ruleCounter++;
		this.type = type;
		this.previousLevel = previousLevel;
	}

//  ----------------------------------------------------------
//  ------------------------   methods   ------------------------
//  ----------------------------------------------------------
	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}

	public RuleDefinition getPreviousLevel() {
		return (previousLevel);
	}

	
	public void setId(int id) {
		this.id = id;
	}

	public int getId() {
		return id;
	}

	public int getValueType() {
		return valueType;
	}

	public void setValueType(int valueType) {
		this.valueType = valueType;
	}
	
	//  ----------------------------------------------------------
//  ------------------------   getNormalizedId   ------------------------
//  ----------------------------------------------------------
	public String getNormalizedId() {
		String result = "";
		int auxCounter = String.valueOf(id).length();
		
		while (auxCounter < 5) {
			result += "0";
			auxCounter++;
		}
		
		return (result + id);
	}; // getNormalizedId


	//  ----------------------------------------------------------
//  ------------------------   getTemporaryVar   ------------------------
//  ----------------------------------------------------------
	public String getTemporaryVar() {
		return ("var" + getNormalizedId());
	}; // getTemporaryVar


	
	public boolean isNumeric() {
		return (valueType == INT_VALUE);
	}

//  ----------------------------------------------------------
//  ------------------------   isPolicyComposition   ------------------------
//  ----------------------------------------------------------
	public boolean isPolicyComposition() {
		if (type == SUBPOLICY_EXPRESSION) {
			return (true);
		}
		else {
			return (false);
		}
	}

//  ----------------------------------------------------------
//  ------------------------   isCompositeExpression   ------------------------
//  ----------------------------------------------------------
	public boolean isCompositeExpression() {
		return (type <= DIVIDE_OPERATOR);
	}

//  ----------------------------------------------------------
//  ------------------------   isBooleanExpression   ------------------------
//  ----------------------------------------------------------
	public boolean isBooleanExpression() {
		return (type <= LESSER_THAN_OPERATOR);
	}

//  ----------------------------------------------------------
//  ------------------------   getTypeDeclaration   ------------------------
//  ----------------------------------------------------------
	public static String getTypeDeclaration(int type) {
		String result = null;
		
		switch (type) {
		case INT_VALUE:
			result = "int ";
			break;
		case BOOLEAN_VALUE:
			result = "boolean ";
			break;
		case STRING_VALUE:
			result = "String ";
			break;

		default:
			break;
		}
		
		return (result);
	} // getTypeDeclaration

//  ----------------------------------------------------------
//  ------------------------   getRelevantEventFields   ------------------------
//  ----------------------------------------------------------
	public Vector getRelevantEventFields() {
		return (null);
	}

//  ----------------------------------------------------------
//  ------------------------   getRelevantCes   ------------------------
//  ----------------------------------------------------------
	public Vector getRelevantCes() {
		return (null);
	}

//  ----------------------------------------------------------
//  ------------------------   keepOnlyThisCes   ------------------------
//  ----------------------------------------------------------
	public RuleDefinition keepOnlyThisCes(String cesName) {
		return (this);
	}


	//  ----------------------------------------------------------
//  ------------------------   ABSTRACT METHODS   ------------------------
//  ----------------------------------------------------------

	public abstract String getFunction();

	public abstract Vector getParameters();

	public abstract RuleDefinition getTimeIndependentCopy();

	public abstract RuleDefinition getCeIndependentCopy();

	public abstract RuleDefinition getObligationIndependentCopy();

	public abstract RuleDefinition getObligation();

	public abstract boolean isObligationDependent();

	public abstract String toString(int tabAdvance);

	public abstract String getSqlRestriction(User currentUser, EventObj ce);

}; // RuleDefinition
